package com.zz.admin.mainTableManagement.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.admin.mainTableManagement.dto.MainTableDto;
import com.zz.admin.mainTableManagement.entity.MainTable;
import com.zz.admin.mainTableManagement.mapper.MainTableMapper;
import com.zz.admin.mainTableManagement.service.MainTableService;
import com.zz.common.base.dto.PageListResultDto;
import com.zz.common.base.enums.BaseExceptionEnum;
import com.zz.common.base.param.QueryParam;
import com.zz.common.constants.BaseConstant;
import com.zz.common.exception.ExceptionFactory;
import com.zz.common.utils.common.UUIDGenerator;
import com.zz.common.utils.mapper.BeanMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import com.zz.admin.subTableManagement.dto.SubTableDto;
import com.zz.admin.subTableManagement.service.SubTableService;

/**
 * 主 服务实现类
 *
 * @author zl
 * @since 2025-11-21 19:50:52
 */
@Service
@Slf4j
public class MainTableServiceImpl extends ServiceImpl<MainTableMapper, MainTable> implements MainTableService {

    @Resource
    private MainTableMapper mainTableMapper;
    @Resource
    private SubTableService subTableService;

    @Override
    public PageListResultDto<MainTableDto> queryWithPage(MainTableDto mainTableDto, QueryParam queryParam) {
        Page<MainTable> page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize());
        QueryWrapper<MainTable> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        if (StringUtils.isNotBlank(mainTableDto.getName())) {
            wrapper.like("name", "%" + mainTableDto.getName() + "%");
        }
        if (StringUtils.isNotBlank(mainTableDto.getDescription())) {
            wrapper.eq("description", mainTableDto.getDescription());
        }
        page = mainTableMapper.selectPage(page, wrapper);
        List<MainTable> mainTables = mainTableMapper.selectList(page, wrapper);
        List<MainTableDto> mainTableDtos = BeanMapper.mapList(mainTables, MainTable.class, MainTableDto.class);
        return new PageListResultDto<>((int) page.getCurrent(), (int) page.getTotal(), queryParam.getPageSize(), mainTableDtos);
    }

    @Override
    public List<MainTableDto> queryWithNoPage(MainTableDto mainTableDto) {
        QueryWrapper<MainTable> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<MainTable> mainTables = mainTableMapper.selectList(wrapper);
        return BeanMapper.mapList(mainTables, MainTable.class, MainTableDto.class);
    }

    @Override
    public MainTableDto queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        MainTable mainTable = mainTableMapper.selectById(id);
        if (mainTable == null || BaseConstant.YES.equals(mainTable.getDelFlag())) {
            return null;
        }
        MainTableDto dto = BeanMapper.map(mainTable, MainTableDto.class);
        List<SubTableDto> subList = subTableService.queryByParentId(dto.getId());
        dto.setSubList(subList);
        return dto;
    }


    @Override
    public List<MainTableDto> queryByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<MainTable> mainTables = mainTableMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(mainTables)) {
            return new ArrayList<>();
        }
        List<MainTableDto> dtos = BeanMapper.mapList(mainTables, MainTable.class, MainTableDto.class);
        for (MainTableDto dto : dtos) {
            if (StringUtils.isNotBlank(dto.getId())) {
                List<SubTableDto> subList = subTableService.queryByParentId(dto.getId());
                dto.setSubList(subList);
            }
        }
        return dtos;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MainTableDto save(MainTableDto mainTableDto) {
        MainTableDto result = insert(mainTableDto);
        if (result != null && result.getSubList() != null && !result.getSubList().isEmpty()) {
            List<SubTableDto> subList = result.getSubList();
            for (SubTableDto sub : subList) {
                sub.setDelFlag(BaseConstant.NO);
                sub.setParentId(result.getId());
            }
            subTableService.saveBatch(subList);
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<MainTableDto> saveBatch(List<MainTableDto> mainTableDtos) {
        List<MainTableDto> results = insertList(mainTableDtos);
        List<SubTableDto> allSubs = new ArrayList<>();
        for (MainTableDto dto : results) {
            if (dto.getSubList() != null && !dto.getSubList().isEmpty()) {
                for (SubTableDto sub : dto.getSubList()) {
                    sub.setDelFlag(BaseConstant.NO);
                    sub.setParentId(dto.getId());
                    allSubs.add(sub);
                }
            }
        }
        if (!allSubs.isEmpty()) {
            subTableService.saveBatch(allSubs);
        }
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MainTableDto modify(MainTableDto mainTableDto) {
        updateById(mainTableDto);
        if (mainTableDto.getSubList() != null && !mainTableDto.getSubList().isEmpty()) {
            for (SubTableDto sub : mainTableDto.getSubList()) {
                sub.setDelFlag(BaseConstant.NO);
                sub.setParentId(mainTableDto.getId());
                if (StringUtils.isBlank(sub.getId())) {
                    subTableService.save(sub);
                } else {
                    subTableService.modify(sub);
                }
            }
        }
        return mainTableDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<MainTableDto> modifyBatch(List<MainTableDto> mainTableDtos) {
        List<MainTableDto> results = updateList(mainTableDtos);
        List<SubTableDto> updateSubs = new ArrayList<>();
        List<SubTableDto> insertSubs = new ArrayList<>();
        for (MainTableDto dto : results) {
            if (dto.getSubList() != null && !dto.getSubList().isEmpty()) {
                for (SubTableDto sub : dto.getSubList()) {
                    sub.setDelFlag(BaseConstant.NO);
                    sub.setParentId(dto.getId());
                    if (StringUtils.isBlank(sub.getId())) {
                        insertSubs.add(sub);
                    } else {
                        updateSubs.add(sub);
                    }
                }
            }
        }
        if (!insertSubs.isEmpty()) {
            subTableService.saveBatch(insertSubs);
        }
        if (!updateSubs.isEmpty()) {
            subTableService.modifyBatch(updateSubs);
        }
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int trueDelete(String id) {
        MainTable entity = new MainTable();
        entity.setId(id);
        return mainTableMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        // 根据业务修改
        MainTableDto mainTableDto = new MainTableDto();
        mainTableDto.setId(id);
        subTableService.deleteByParentId(String.valueOf(id));
        deleteById(mainTableDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatch(List<String> ids) {
        // 根据业务修改
        List<String> parentIds = new ArrayList<>();
        for (String id : ids) {
            parentIds.add(String.valueOf(id));
        }
        if (!parentIds.isEmpty()) {
            subTableService.deleteByParentIds(parentIds);
        }
        deleteByIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MainTableDto insert(MainTableDto mainTableDto) {
        mainTableDto.setId(UUIDGenerator.generateUUID());
        mainTableDto.setDelFlag(BaseConstant.NO);
        MainTable entity = BeanMapper.map(mainTableDto, MainTable. class);
        mainTableMapper.insert(entity);
        return mainTableDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MainTableDto insertWithId(MainTableDto mainTableDto) {
        if (StringUtils.isBlank(mainTableDto.getId())) {
            mainTableDto.setId(UUIDGenerator.generateUUID());
        }
        mainTableDto.setDelFlag(BaseConstant.NO);
        MainTable entity = BeanMapper.map(mainTableDto, MainTable.class);
        mainTableMapper.insert(entity);
        return mainTableDto;
    }

    private List<MainTableDto> insertList(List<MainTableDto> mainTableDtos) {
        if (CollectionUtils.isEmpty(mainTableDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量插入时，参数不能为空");
        }
        List<MainTable> insertList = new ArrayList<>();
        for (MainTableDto mainTableDto : mainTableDtos) {
            if (StringUtils.isBlank(mainTableDto.getId())) {
                mainTableDto.setId(UUIDGenerator.generateUUID());
            }
            mainTableDto.setDelFlag(BaseConstant.NO);
            insertList.add(BeanMapper.map(mainTableDto, MainTable.class));
        }
        mainTableMapper.insert(insertList, 1000);
        return mainTableDtos;
    }

    private List<MainTableDto> updateList(List<MainTableDto> mainTableDtos) {
        if (CollectionUtils.isEmpty(mainTableDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量更新时，参数不能为空");
        }
        for (MainTableDto mainTableDto : mainTableDtos) {
            if (StringUtils.isBlank(mainTableDto.getId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量更新时，主键不能为空");
            }
        }
        List<MainTable> mainTableList = BeanMapper.mapList(mainTableDtos, MainTableDto.class, MainTable.class);
        mainTableMapper.updateById(mainTableList, 1000);
        return mainTableDtos;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateById(MainTableDto mainTableDto) {
        if (StringUtils.isBlank(mainTableDto.getId())) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "更新时，主键不能为空");
        }
        MainTable entity = BeanMapper.map(mainTableDto, MainTable.class);
        return mainTableMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public int deleteById(MainTableDto mainTableDto) {
        mainTableDto.setDelFlag(BaseConstant.YES);
        return updateById(mainTableDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量删除时，参数不能为空");
        }
        for (String id : ids) {
            MainTableDto mainTableDto = new MainTableDto();
            mainTableDto.setId(id);
            mainTableDto.setDelFlag(BaseConstant.YES);
            updateById(mainTableDto);
        }
    }

}
